package month.statistic;

import entity.month.DistPortrait;
import entity.month.DistVehicle;
import entity.month.VehicleNum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import utility.database.SqlServerAccess;
import utility.time.ProcessTime;

import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * 处理区域画像数据表
 * @author lit
 * @date 2018/3/20.
 */
public class ProcessDistPortrait {
    //数据连接
    private Connection connection = null;
    private PreparedStatement preparedStatement = null;
    private SqlServerAccess mssql = null;
    //中心城区
    private static final HashSet<Integer> centerCityDistID = new HashSet<Integer>(){
        {
            add(205);//朝阳区
            add(206);//海淀区
            add(207);//丰台区
            add(208);//石景山区
            add(209);//东城区
            add(210);//西城区
        }
    };
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
    private SimpleDateFormat sdfLocal = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private Logger logger = null;

    private boolean initMSSQL(){
        if( mssql == null ){
            try {
                mssql = new SqlServerAccess();
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
        }
        if( connection == null ){
            try {
                connection = mssql.getInstance();
                connection.setAutoCommit(false);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    private void finishMSSQL(){
        if(connection != null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(preparedStatement != null){
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    public void processDistPortrait(String[] statTime) {
        logger = LoggerFactory.getLogger(ProcessDistPortrait.class);
        HashMap<Integer,DistPortrait> distPortraitMap = new HashMap<>(30);
        int year = ProcessTime.getYear(statTime[1]);
        int month = ProcessTime.getMonth(statTime[1]);
        logger.info("即将清除区域画像已有{}年{}月数据",year,month);
        clearDistPortrait(year,month);

        logger.info("获取区域画像基础数据");
        getDistBaseInfo(statTime,distPortraitMap);

        logger.info("获取车辆数");
        getVehicleNum(statTime,distPortraitMap);

        logger.info("获取在线车辆数");
        getOnlineVehicleNum(statTime,distPortraitMap);

        logger.info("获取最大点火车辆数");
        getMaxFireVehicleNum(statTime,distPortraitMap);

        logger.info("区域画像数据插入数据库");
        addDistPortraitData(statTime,distPortraitMap);
        logger.info("区域画像数据表操作结束");
        finishMSSQL();
    }

    private void clearDistPortrait(int year, int month) {
        if(initMSSQL()){
            String sql = "delete FROM IDBox_Master.dbo.stat_month_distPortrait where StatYear = ? and StatMonth = ?";
            try{
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setInt(1,year);
                preparedStatement.setInt(2,month);
                int num = preparedStatement.executeUpdate();
                connection.commit();
                logger.info("删除区域画像数据{}条",num);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 5. 向数据库中添加区域画像数据
     * @param statTime
     * @param distPortraitMap
     */
    private void addDistPortraitData(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        if(initMSSQL()){
            String sql = "insert into IDBox_Master.dbo.stat_month_distPortrait (StatYear,StatMonth,DistID,ID_POI,DistName,LocalVehicleNum,LocalVehicleNumExt,BJLocalVehicleNum,NotBJLocalVehicleNum,BJLocalVehicleNumExt,NotBJLocalVehicleNumExt,MaxOnlineNum,MaxOnlineNumExt,BJMaxOnlineNum,BJMaxOnlineNumExt,NotBJMaxOnlineNum,NotBJMaxOnlineNumExt,MaxFireNum,MaxFireNumExt,BJMaxFireNum,BJMaxFireNumExt,NotBJMaxFireNum,NotBJMaxFireNumExt) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
            int year = ProcessTime.getYear(statTime[1]);
            int month = ProcessTime.getMonth(statTime[1]);
            try{
                preparedStatement = connection.prepareStatement(sql);
                for(int id : distPortraitMap.keySet()){
                    DistPortrait distPortrait = distPortraitMap.get(id);
                    preparedStatement.setInt(1,year);
                    preparedStatement.setInt(2,month);
                    preparedStatement.setInt(3,distPortrait.getDistID());
                    preparedStatement.setInt(4,distPortrait.getId_poi());
                    preparedStatement.setString(5,distPortrait.getDistName());
                    preparedStatement.setInt(6,distPortrait.getLocalVehicleNum());
                    preparedStatement.setInt(7,distPortrait.getLocalVehicleNumExt());
                    preparedStatement.setInt(8,distPortrait.getBjLocalVehicleNum());
                    preparedStatement.setInt(9,distPortrait.getNotBJLocalVehicleNum());
                    preparedStatement.setInt(10,distPortrait.getBjLocalVehicleNumExt());
                    preparedStatement.setInt(11,distPortrait.getNotBJLocalVehicleNumExt());
                    preparedStatement.setInt(12,distPortrait.getMaxOnlineNum());
                    preparedStatement.setInt(13,distPortrait.getMaxOnlineNumExt());
                    preparedStatement.setInt(14,distPortrait.getBjMaxOnlineNum());
                    preparedStatement.setInt(15,distPortrait.getBjMaxOnlineNumExt());
                    if(distPortrait.getNotBJMaxOnlineNum() != null){
                        preparedStatement.setInt(16,distPortrait.getNotBJMaxOnlineNum());
                    }else{
                        preparedStatement.setNull(16,Types.INTEGER);
                    }
                    if(distPortrait.getNotBJMaxOnlineNumExt() != null){
                        preparedStatement.setInt(17,distPortrait.getNotBJMaxOnlineNumExt());
                    }else{
                        preparedStatement.setNull(17,Types.INTEGER);
                    }
                   if(distPortrait.getMaxFireNum() != null){
                       preparedStatement.setInt(18,distPortrait.getMaxFireNum());
                   }else{
                       preparedStatement.setNull(18,Types.INTEGER);
                   }
                   if(distPortrait.getMaxFireNumExt() != null){
                       preparedStatement.setInt(19,distPortrait.getMaxFireNumExt());
                   }else{
                       preparedStatement.setNull(19,Types.INTEGER);
                   }
                   if(distPortrait.getBjMaxFireNum() != null){
                       preparedStatement.setInt(20,distPortrait.getBjMaxFireNum());
                   }else{
                       preparedStatement.setNull(20,Types.INTEGER);
                   }
                   if(distPortrait.getBjMaxFireNumExt() != null){
                       preparedStatement.setInt(21,distPortrait.getBjMaxFireNumExt());
                   }else{
                       preparedStatement.setNull(21,Types.INTEGER);
                   }
                   if(distPortrait.getNotBJMaxFireNum() != null){
                       preparedStatement.setInt(22,distPortrait.getNotBJMaxFireNum());
                   }else{
                       preparedStatement.setNull(22,Types.INTEGER);
                   }
                    if(distPortrait.getNotBJMaxFireNumExt() != null){
                       preparedStatement.setInt(23,distPortrait.getNotBJMaxFireNumExt());
                   }else{
                       preparedStatement.setNull(23,Types.INTEGER);
                   }
                    preparedStatement.addBatch();
                }
                preparedStatement.executeBatch();
                connection.commit();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 1.获取区域的基础信息
     * @param distPortraitMap
     * @param statTime
     */
    private void getDistBaseInfo(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        if(initMSSQL()){
            /**
             * 区域
             */
            String sql = "SELECT a.DistId,a.ID_POI,a.NAME as DistName,COUNT (*) as LocalVehicleNum,SUM (b.BoxWeight) as LocalVehicleNumExt FROM IDBox_Base.[dbo].BJ_Area a INNER JOIN IDBox_Master.dbo.[stat_month_userPortrait] b ON b.home_dist = a.ID_POI WHERE b.StatMonth = ? AND b.StatYear = ? GROUP BY a.DistId,a.ID_POI,a.NAME";
            /**
             * 环路
             */
            sql += " UNION ALL SELECT a.DistId,a.ID_POI,a.NAME as DistName,COUNT (*) as LocalVehicleNum,SUM (b.BoxWeight) as LocalVehicleNumExt FROM IDBox_Base.[dbo].BJ_Area a INNER JOIN IDBox_Master.dbo.[stat_month_userPortrait] b ON b.home_ring = a.ID_POI WHERE b.StatMonth = ? AND b.StatYear = ? GROUP BY a.DistId,a.ID_POI,a.NAME";
            /**
             * 全市域
             */
            sql += " UNION ALL SELECT 1000 as DistId,1000 as ID_POI,'全市域' as DistName,COUNT (*) as LocalVehicleNum,SUM (BoxWeight) as LocalVehicleNumExt FROM IDBox_Master.dbo.[stat_month_userPortrait] WHERE StatMonth = ? AND StatYear = ? AND home_dist IS NOT NULL";
            /**
             * 中心城区
             */
            sql += " UNION ALL SELECT 100 as DistId,100 as ID_POI,'中心城区' as DistName,COUNT (*) as LocalVehicleNum,SUM (BoxWeight) as LocalVehicleNumExt FROM IDBox_Master.dbo.[stat_month_userPortrait] WHERE StatMonth = ? AND StatYear = ? AND home_dist < 9";

            int year = ProcessTime.getYear(statTime[1]);
            int month = ProcessTime.getMonth(statTime[1]);

            try{
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setInt(1,month);
                preparedStatement.setInt(2,year);
                preparedStatement.setInt(3,month);
                preparedStatement.setInt(4,year);
                preparedStatement.setInt(5,month);
                preparedStatement.setInt(6,year);
                preparedStatement.setInt(7,month);
                preparedStatement.setInt(8,year);
                if(preparedStatement != null){
                    ResultSet resultSet = preparedStatement.executeQuery();
                    while(resultSet.next()){
                        DistPortrait distPortrait = new DistPortrait();
                        distPortrait.setStatYear(year);
                        distPortrait.setStatMonth(month);
                        int distID = resultSet.getInt("DistID");
                        distPortrait.setDistID(distID);
                        distPortrait.setId_poi(resultSet.getInt("ID_POI"));
                        distPortrait.setDistName(resultSet.getString("DistName"));
                        distPortrait.setLocalVehicleNum(resultSet.getInt("LocalVehicleNum"));
                        int temp = resultSet.getInt("LocalVehicleNumExt");
                        distPortrait.setLocalVehicleNumExt(resultSet.getInt("LocalVehicleNumExt"));

                        distPortraitMap.put(distID,distPortrait);
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 2.获取车辆数，京牌车辆数，非京牌车辆数，及相应的扩样后数量
     * @param statTime
     * @param distPortraitMap
     */
    private void getVehicleNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        getBJVehicleNum(statTime,distPortraitMap);
        getNotBJVehicleNum(statTime,distPortraitMap);
    }

    /**
     * 2.1 获取京牌车辆数及扩样后
     * @param statTime
     * @param distPortraitMap
     */
    private void getBJVehicleNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        if(initMSSQL()){
            /**
             * 区域
             */
            String sql = "SELECT a.DistId,COUNT (*) AS BJLocalVehicleNum,SUM (b.BoxWeight) AS BJLocalVehicleNumExt FROM IDBox_Base.[dbo].BJ_Area a LEFT JOIN IDBox_Master.[dbo].[stat_month_userPortrait] b ON b.home_dist = a.ID_POI WHERE a.ID_POI IS NOT NULL AND PlateNum LIKE '京%' AND b.StatMonth = ? AND b.StatYear = ? GROUP BY a.DistId";

            /**
             * 环路
             */
            sql += " UNION ALL SELECT a.DistId,COUNT (*) AS BJLocalVehicleNum,SUM (b.BoxWeight) AS BJLocalVehicleNumExt FROM IDBox_Base.[dbo].BJ_Area a LEFT JOIN IDBox_Master.[dbo].[stat_month_userPortrait] b ON b.home_ring = a.ID_POI WHERE a.ID_POI IS NOT NULL AND PlateNum LIKE '京%' AND b.StatMonth = ? AND b.StatYear = ? GROUP BY a.DistId";
            /**
             * 全市域
             */
            sql += " UNION ALL SELECT 1000 AS DistId,COUNT (*) AS BJLocalVehicleNum,SUM (BoxWeight) AS BJLocalVehicleNumExt FROM  IDBox_Master.[dbo].[stat_month_userPortrait] WHERE home_dist IS NOT NULL AND PlateNum LIKE '京%' AND StatMonth = ? AND StatYear = ?";

            /**
             * 中心城区
             */
            sql += " UNION ALL SELECT 100 AS DistId,COUNT (*) AS BJLocalVehicleNum,SUM (b.BoxWeight) AS BJLocalVehicleNumExt FROM IDBox_Base.[dbo].BJ_Area a LEFT JOIN IDBox_Master.[dbo].[stat_month_userPortrait] b ON b.home_ring = a.ID_POI WHERE a.ID_POI IS NOT NULL AND PlateNum LIKE '京%' AND b.StatMonth = ? AND b.StatYear = ? AND home_Dist < 9";

            int year = ProcessTime.getYear(statTime[1]);
            int month = ProcessTime.getMonth(statTime[1]);

            try{
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setInt(1,month);
                preparedStatement.setInt(2,year);
                preparedStatement.setInt(3,month);
                preparedStatement.setInt(4,year);
                preparedStatement.setInt(5,month);
                preparedStatement.setInt(6,year);
                preparedStatement.setInt(7,month);
                preparedStatement.setInt(8,year);
                if(preparedStatement != null){
                    ResultSet resultSet = preparedStatement.executeQuery();
                    while(resultSet.next()){
                        int distID = resultSet.getInt("DistId");
                        DistPortrait distPortrait = distPortraitMap.get(distID);
                        distPortrait.setBjLocalVehicleNum(resultSet.getInt("BJLocalVehicleNum"));
                        distPortrait.setBjLocalVehicleNumExt(resultSet.getInt("BJLocalVehicleNumExt"));
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 2.2 获取非京牌车辆数及扩样后
     * @param statTime
     * @param distPortraitMap
     */
    private void getNotBJVehicleNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        if(initMSSQL()){
            /**
             * 区域
             */
            String sql = "SELECT a.DistId,COUNT (*) AS NotBJLocalVehicleNum,SUM (b.BoxWeight) AS NotBJLocalVehicleNumExt FROM IDBox_Base.[dbo].BJ_Area a LEFT JOIN IDBox_Master.[dbo].[stat_month_userPortrait] b ON b.home_dist = a.ID_POI WHERE a.ID_POI IS NOT NULL AND PlateNum NOT LIKE '京%' AND b.StatMonth = ? AND b.StatYear = ? GROUP BY a.DistId";
            /**
             * 环路
             */
            sql += " UNION ALL SELECT a.DistId,COUNT (*) AS NotBJLocalVehicleNum,SUM (b.BoxWeight) AS NotBJLocalVehicleNumExt FROM IDBox_Base.[dbo].BJ_Area a LEFT JOIN IDBox_Master.[dbo].[stat_month_userPortrait] b ON b.home_ring = a.ID_POI WHERE a.ID_POI IS NOT NULL AND PlateNum NOT LIKE '京%' AND b.StatMonth = ? AND b.StatYear = ? GROUP BY a.DistId";
            /**
             * 全市域
             */
            sql += " UNION ALL SELECT 1000 AS DistId,COUNT (*) AS NotBJLocalVehicleNum,SUM (BoxWeight) AS NotBJLocalVehicleNumExt FROM  IDBox_Master.[dbo].[stat_month_userPortrait] WHERE home_dist IS NOT NULL AND PlateNum NOT LIKE '京%' AND StatMonth = ? AND StatYear = ?";

            /**
             * 中心城区
             */
            sql += " UNION ALL SELECT 100 AS DistId,COUNT (*) AS NotBJLocalVehicleNum,SUM (b.BoxWeight) AS NotBJLocalVehicleNumExt FROM IDBox_Base.[dbo].BJ_Area a LEFT JOIN IDBox_Master.[dbo].[stat_month_userPortrait] b ON b.home_ring = a.ID_POI WHERE a.ID_POI IS NOT NULL AND PlateNum NOT LIKE '京%' AND b.StatMonth = ? AND b.StatYear = ? AND home_Dist < 9";

            int year = ProcessTime.getYear(statTime[1]);
            int month = ProcessTime.getMonth(statTime[1]);

            try{
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setInt(1,month);
                preparedStatement.setInt(2,year);
                preparedStatement.setInt(3,month);
                preparedStatement.setInt(4,year);
                preparedStatement.setInt(5,month);
                preparedStatement.setInt(6,year);
                preparedStatement.setInt(7,month);
                preparedStatement.setInt(8,year);
                if(preparedStatement != null){
                    ResultSet resultSet = preparedStatement.executeQuery();
                    while(resultSet.next()){
                        int distID = resultSet.getInt("DistId");
                        DistPortrait distPortrait = distPortraitMap.get(distID);
                        distPortrait.setNotBJLocalVehicleNum(resultSet.getInt("NotBJLocalVehicleNum"));
                        distPortrait.setNotBJLocalVehicleNumExt(resultSet.getInt("NotBJLocalVehicleNumExt"));
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 3.获取在线车辆数相关值
     * @param statTime
     * @param distPortraitMap
     */
    private void getOnlineVehicleNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        getMaxOnlineVehicleNum(statTime,distPortraitMap);
        getBJMaxOnlineVehicleNum(statTime,distPortraitMap);
        getNotBJMaxOnlineVehicleNum(statTime,distPortraitMap);
    }

    /**
     * 3.1 获取最大在线车辆数
     * @param statTime
     * @param distPortraitMap
     */
    private void getMaxOnlineVehicleNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        String sql = "select a.TripStartTime,a.TripEndTime,b.DistID,a.StartRing as RingID,a.VID,ISNULL(c.BoxWeight,0.0) as BoxWeight from (SELECT TripStartTime,TripEndTime,StartRing,VID,StartDist FROM rtm_trip WHERE TripStartTime >= ? AND TripStartTime < ? )a LEFT JOIN [IDBox_Base].[dbo].[BJ_Area] b ON (a.StartDist = b.ID_POI) left JOIN (select vid,BoxWeight from IDBox_Master.dbo.stat_month_userPortrait where statMonth = ? and statYear = ?) c ON a.VID = c.VID";
        try{
            ArrayList<DistVehicle> distVehicleList = getTripDistVehicleNum(statTime,sql);

            Map<Integer,Map<String,VehicleNum>> distVehicleNumMap = processOnlineVehicleNum(distVehicleList);

            //赋值更新区域画像的最大在线车辆数
            for(int id : distVehicleNumMap.keySet()){
                //由间隔五分钟的时间字符串作为key，车辆数及扩样车辆数对象作为value
                Map<String,VehicleNum> fiveMinuteVehicleNum = distVehicleNumMap.get(id);
                int maxVehicleNum = getNum(fiveMinuteVehicleNum);
                int maxVehicleNumExt = getNumExt(fiveMinuteVehicleNum);

                DistPortrait distPortrait = distPortraitMap.get(id);
                if(distPortrait != null){
                    distPortrait.setMaxOnlineNum(maxVehicleNum);
                    distPortrait.setMaxOnlineNumExt(maxVehicleNumExt);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 3.1.1 获取和车辆数相关的出行记录，把sql跑出来的数据记录存到对象里
     * @param statTime
     * @param sql
     * @return
     */
    private ArrayList<DistVehicle> getTripDistVehicleNum(String[] statTime,String sql){
        ArrayList<DistVehicle> distVehicleList = new ArrayList<>();
        if(initMSSQL()){
            int month = ProcessTime.getMonth(statTime[1]);
            int year = ProcessTime.getYear(statTime[1]);
            try{
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setString(1,statTime[1]);
                preparedStatement.setString(2,statTime[2]);
                preparedStatement.setInt(3,month);
                preparedStatement.setInt(4,year);
                if(preparedStatement != null){
                    ResultSet resultSet = preparedStatement.executeQuery();

                    while(resultSet.next()){
                        Timestamp tripStartTime = resultSet.getTimestamp("TripStartTime");
                        Timestamp tripEndTime = resultSet.getTimestamp("TripEndTime");
                        int distID = resultSet.getInt("DistID");
                        String ringID = resultSet.getString("RingID");
                        Float boxWeight = resultSet.getFloat("BoxWeight");
                        DistVehicle distVehicle = new DistVehicle();
                        distVehicle.setTripStartTime(tripStartTime);
                        distVehicle.setTripEndTime(tripEndTime);
                        distVehicle.setDistID(distID);
                        if(ringID != null && ringID.length() > 0){
                            distVehicle.setRingID(Integer.parseInt(ringID));
                        }
                        distVehicle.setBoxWeight(boxWeight);

                        distVehicleList.add(distVehicle);
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return distVehicleList;
    }

    /**
     * 3.1.2 处理查询的数据，获取五分钟在线车辆数相关指标
     * @param distVehicleList
     * @return
     */
    private Map<Integer,Map<String,VehicleNum>> processOnlineVehicleNum(ArrayList<DistVehicle> distVehicleList) {
        Map<Integer,Map<String,VehicleNum>> distVehicleNumMap = new HashMap<>();
        try{
            for(int i = 0; i < distVehicleList.size(); i++){
                DistVehicle distVehicle = distVehicleList.get(i);
                Timestamp tripStartTime = distVehicle.getTripStartTime();
                Timestamp tripEndTime = distVehicle.getTripEndTime();
                int distID = distVehicle.getDistID();
                int ringID = 0;
                if(distVehicle.getRingID() != null){
                    ringID = distVehicle.getRingID();
                }

                float boxWeight = distVehicle.getBoxWeight();
                //区域
                if(distID > 0){
                    if(!distVehicleNumMap.containsKey(distID)){
                        distVehicleNumMap.put(distID,new HashMap<>());
                    }
                }
                //环路
                if(ringID > 0){
                    if(!distVehicleNumMap.containsKey(ringID)){
                        distVehicleNumMap.put(ringID,new HashMap<>());
                    }
                }
                //中心城区
                if(!distVehicleNumMap.containsKey(100)){
                    distVehicleNumMap.put(100,new HashMap<>());
                }
                //全市域
                if(!distVehicleNumMap.containsKey(1000)){
                    distVehicleNumMap.put(1000,new HashMap<>());
                }

                String lowerBound = sdf.format(tripStartTime).substring(0, 10) + String.format("%02d", 5 * ( Integer.parseInt( sdf.format(tripStartTime).substring(10, 12) ) / 5 ) );
                Timestamp temp = new Timestamp(sdf.parse(lowerBound).getTime());
                while( temp.getTime() < tripEndTime.getTime() ){
                    String key = sdf.format(temp);
                    //区域
                    if(distID > 0){
                        Map<String,VehicleNum> areaMap = distVehicleNumMap.get(distID);
                        if(areaMap.containsKey(key)){
                            VehicleNum vehicleNum = areaMap.get(key);
                            vehicleNum.setNum(vehicleNum.getNum() + 1);
                            vehicleNum.setNumExt(vehicleNum.getNumExt() + boxWeight);
                            areaMap.replace(key,vehicleNum);
                        }else{
                            VehicleNum vehicleNum = new VehicleNum();
                            vehicleNum.setNum(1);
                            vehicleNum.setNumExt(boxWeight);
                            areaMap.put(key,vehicleNum);
                        }
                    }

                    //环路
                    if(ringID > 0){
                        Map<String,VehicleNum> ringMap = distVehicleNumMap.get(ringID);
                        if(ringMap.containsKey(key)){
                            VehicleNum vehicleNum = ringMap.get(key);
                            vehicleNum.setNum(vehicleNum.getNum() + 1);
                            vehicleNum.setNumExt(vehicleNum.getNumExt() + boxWeight);
                            ringMap.replace(key,vehicleNum);
                        }else{
                            VehicleNum vehicleNum = new VehicleNum();
                            vehicleNum.setNum(1);
                            vehicleNum.setNumExt(boxWeight);
                            ringMap.put(key,vehicleNum);
                        }
                    }

                    //中心城区
                    //判断区域是否属于中心城区
                    if(distID > 0 && centerCityDistID.contains(distID)){
                        Map<String,VehicleNum> centerCityMap = distVehicleNumMap.get(100);
                        if(centerCityMap.containsKey(key)){
                            VehicleNum vehicleNum = centerCityMap.get(key);
                            vehicleNum.setNum(vehicleNum.getNum() + 1);
                            vehicleNum.setNumExt(vehicleNum.getNumExt() + boxWeight);
                            centerCityMap.replace(key,vehicleNum);
                        }else{
                            VehicleNum vehicleNum = new VehicleNum();
                            vehicleNum.setNum(1);
                            vehicleNum.setNumExt(boxWeight);
                            centerCityMap.put(key,vehicleNum);
                        }
                    }
                    //全市域
                    Map<String,VehicleNum> citywideMap = distVehicleNumMap.get(1000);
                    if(citywideMap.containsKey(key)){
                        VehicleNum vehicleNum = citywideMap.get(key);
                        vehicleNum.setNum(vehicleNum.getNum() + 1);
                        vehicleNum.setNumExt(vehicleNum.getNumExt() + boxWeight);
                        citywideMap.replace(key,vehicleNum);
                    }else{
                        VehicleNum vehicleNum = new VehicleNum();
                        vehicleNum.setNum(1);
                        vehicleNum.setNumExt(boxWeight);
                        citywideMap.put(key,vehicleNum);
                    }

                    //增加五分钟间隔，毫秒数
                    temp = new Timestamp(temp.getTime() + 60*1000*5);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return distVehicleNumMap;
    }

    /**
     * 3.2 获取京牌车辆最大在线数
     * @param statTime
     * @param distPortraitMap
     */
    private void getBJMaxOnlineVehicleNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        String sql = "select a.TripStartTime,a.TripEndTime,b.DistID,a.StartRing as RingID,a.VID,ISNULL(c.BoxWeight,0.0) as BoxWeight from (SELECT TripStartTime,TripEndTime,StartRing,VID,StartDist FROM rtm_trip WHERE TripStartTime >= ? AND TripStartTime < ? AND PlateNum LIKE '京%')a LEFT JOIN [IDBox_Base].[dbo].[BJ_Area] b ON (a.StartDist = b.ID_POI) left JOIN (select vid,BoxWeight from IDBox_Master.dbo.stat_month_userPortrait where statMonth = ? and statYear = ?) c ON a.VID = c.VID";
        try{
            ArrayList<DistVehicle> distVehicleList = getTripDistVehicleNum(statTime,sql);

            Map<Integer,Map<String,VehicleNum>> distVehicleNumMap = processOnlineVehicleNum(distVehicleList);

            //赋值更新区域画像的京牌车最大在线车辆数
            for(int id : distVehicleNumMap.keySet()){
                //由间隔五分钟的时间字符串作为key，车辆数及扩样车辆数对象作为value
                Map<String,VehicleNum> fiveMinuteVehicleNum = distVehicleNumMap.get(id);
                int maxVehicleNum = getNum(fiveMinuteVehicleNum);
                int maxVehicleNumExt = getNumExt(fiveMinuteVehicleNum);
                DistPortrait distPortrait = distPortraitMap.get(id);
                if(distPortrait != null){
                    distPortrait.setBjMaxOnlineNum(maxVehicleNum);
                    distPortrait.setBjMaxOnlineNumExt(maxVehicleNumExt);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 3.3 获取非京牌车辆最大在线数
     * @param statTime
     * @param distPortraitMap
     */
    private void getNotBJMaxOnlineVehicleNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        String sql = "select a.TripStartTime,a.TripEndTime,b.DistID,a.StartRing as RingID,a.VID,ISNULL(c.BoxWeight,0.0) as BoxWeight from (SELECT TripStartTime,TripEndTime,StartRing,VID,StartDist FROM rtm_trip WHERE TripStartTime >= ? AND TripStartTime < ? AND PlateNum NOT LIKE '京%')a LEFT JOIN [IDBox_Base].[dbo].[BJ_Area] b ON (a.StartDist = b.ID_POI) left JOIN (select vid,BoxWeight from IDBox_Master.dbo.stat_month_userPortrait where statMonth = ? and statYear = ?) c ON a.VID = c.VID";
        try{
            ArrayList<DistVehicle> distVehicleList = getTripDistVehicleNum(statTime,sql);

            Map<Integer,Map<String,VehicleNum>> distVehicleNumMap = processOnlineVehicleNum(distVehicleList);

            //赋值更新区域画像的非京牌车最大在线车辆数
            for(int id : distVehicleNumMap.keySet()){
                //由间隔五分钟的时间字符串作为key，车辆数及扩样车辆数对象作为value
                Map<String,VehicleNum> fiveMinuteVehicleNum = distVehicleNumMap.get(id);
                int maxVehicleNum = getNum(fiveMinuteVehicleNum);
                int maxVehicleNumExt = getNumExt(fiveMinuteVehicleNum);
                DistPortrait distPortrait = distPortraitMap.get(id);
                if(distPortrait != null){
                    distPortrait.setNotBJMaxOnlineNum(maxVehicleNum);
                    distPortrait.setNotBJMaxOnlineNumExt(maxVehicleNumExt);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 4.获取点火车辆数相关值
     * @param statTime
     * @param distPortraitMap
     */
    private void getMaxFireVehicleNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        getMaxFireVehilceNum(statTime,distPortraitMap);
        getBJMaxFireVehicleNum(statTime,distPortraitMap);
        getNotBJMaxFireVehicleNum(statTime,distPortraitMap);
    }

    /**
     * 4.1 获取最大点火车辆数
     * @param statTime
     * @param distPortraitMap
     */
    private void getMaxFireVehilceNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        String sql = "select a.TripStartTime,a.TripEndTime,b.DistID,a.StartRing as RingID,a.VID,ISNULL(c.BoxWeight,0.0) as BoxWeight from (SELECT TripStartTime,TripEndTime,StartRing,VID,StartDist FROM rtm_trip WHERE TripStartTime >= ? AND TripStartTime < ? )a LEFT JOIN [IDBox_Base].[dbo].[BJ_Area] b ON (a.StartDist = b.ID_POI) left JOIN (select vid,BoxWeight from IDBox_Master.dbo.stat_month_userPortrait where statMonth = ? and statYear = ?) c ON a.VID = c.VID";
        try{
            ArrayList<DistVehicle> distVehicleList = getTripDistVehicleNum(statTime,sql);

            Map<Integer,Map<String,VehicleNum>> distVehicleNumMap = processFireVehicleNum(distVehicleList);

            //赋值更新区域画像的最大在线车辆数
            for(int id : distVehicleNumMap.keySet()){
                //由间隔五分钟的时间字符串作为key，车辆数及扩样车辆数对象作为value
                Map<String,VehicleNum> fiveMinuteVehicleNum = distVehicleNumMap.get(id);
                int maxVehicleNum = getNum(fiveMinuteVehicleNum);
                int maxVehicleNumExt = getNumExt(fiveMinuteVehicleNum);

                DistPortrait distPortrait = distPortraitMap.get(id);

                if(distPortrait != null){
                    distPortrait.setMaxFireNum(maxVehicleNum);
                    distPortrait.setMaxFireNumExt(maxVehicleNumExt);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 4.1.1 处理查询的数据，获取五分钟点火车辆数相关指标
     * @param distVehicleList
     * @return
     */
    private Map<Integer,Map<String,VehicleNum>> processFireVehicleNum(ArrayList<DistVehicle> distVehicleList) {
        Map<Integer,Map<String,VehicleNum>> distVehicleNumMap = new HashMap<>();
        try{
            for(int i = 0; i < distVehicleList.size(); i++){
                DistVehicle distVehicle = distVehicleList.get(i);
                Timestamp tripStartTime = distVehicle.getTripStartTime();
                int distID = distVehicle.getDistID();
                int ringID = 0;
                if(distVehicle.getRingID() != null){
                    ringID = distVehicle.getRingID();
                }
                float boxWeight = distVehicle.getBoxWeight();
                //区域
                if(distID > 0){
                    if(!distVehicleNumMap.containsKey(distID)){
                        distVehicleNumMap.put(distID,new HashMap<>());
                    }
                }
                //环路
                if(ringID > 0){
                    if(!distVehicleNumMap.containsKey(ringID)){
                        distVehicleNumMap.put(ringID,new HashMap<>());
                    }
                }

                //中心城区
                if(!distVehicleNumMap.containsKey(100)){
                    distVehicleNumMap.put(100,new HashMap<>());
                }
                //全市域
                if(!distVehicleNumMap.containsKey(1000)){
                    distVehicleNumMap.put(1000,new HashMap<>());
                }

                String key = sdf.format(tripStartTime).substring(0, 10) + String.format("%02d", 5 * ( Integer.parseInt( sdf.format(tripStartTime).substring(10, 12) ) / 5 ) );

                //区域
                if(distID > 0){
                    Map<String,VehicleNum> areaMap = distVehicleNumMap.get(distID);
                    if(areaMap.containsKey(key)){
                        VehicleNum vehicleNum = areaMap.get(key);
                        vehicleNum.setNum(vehicleNum.getNum() + 1);
                        vehicleNum.setNumExt(vehicleNum.getNumExt() + boxWeight);
                        areaMap.replace(key,vehicleNum);
                    }else{
                        VehicleNum vehicleNum = new VehicleNum();
                        vehicleNum.setNum(1);
                        vehicleNum.setNumExt(boxWeight);
                        areaMap.put(key,vehicleNum);
                    }
                }

                //环路
                if(ringID > 0){
                    Map<String,VehicleNum> ringMap = distVehicleNumMap.get(ringID);
                    if(ringMap.containsKey(key)){
                        VehicleNum vehicleNum = ringMap.get(key);
                        vehicleNum.setNum(vehicleNum.getNum() + 1);
                        vehicleNum.setNumExt(vehicleNum.getNumExt() + boxWeight);
                        ringMap.replace(key,vehicleNum);
                    }else{
                        VehicleNum vehicleNum = new VehicleNum();
                        vehicleNum.setNum(1);
                        vehicleNum.setNumExt(boxWeight);
                        ringMap.put(key,vehicleNum);
                    }
                }

                //中心城区
                //判断区域是否属于中心城区
                if(distID > 0 && centerCityDistID.contains(distID)){
                    Map<String,VehicleNum> centerCityMap = distVehicleNumMap.get(100);
                    if(centerCityMap.containsKey(key)){
                        VehicleNum vehicleNum = centerCityMap.get(key);
                        vehicleNum.setNum(vehicleNum.getNum() + 1);
                        vehicleNum.setNumExt(vehicleNum.getNumExt() + boxWeight);
                        centerCityMap.replace(key,vehicleNum);
                    }else{
                        VehicleNum vehicleNum = new VehicleNum();
                        vehicleNum.setNum(1);
                        vehicleNum.setNumExt(boxWeight);
                        centerCityMap.put(key,vehicleNum);
                    }
                }
                //全市域
                Map<String,VehicleNum> citywideMap = distVehicleNumMap.get(1000);
                if(citywideMap.containsKey(key)){
                    VehicleNum vehicleNum = citywideMap.get(key);
                    vehicleNum.setNum(vehicleNum.getNum() + 1);
                    vehicleNum.setNumExt(vehicleNum.getNumExt() + boxWeight);
                    citywideMap.replace(key,vehicleNum);
                }else{
                    VehicleNum vehicleNum = new VehicleNum();
                    vehicleNum.setNum(1);
                    vehicleNum.setNumExt(boxWeight);
                    citywideMap.put(key,vehicleNum);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return distVehicleNumMap;
    }

    /**
     * 4.2 获取京牌车最大点火车辆数
     * @param statTime
     * @param distPortraitMap
     */
    private void getBJMaxFireVehicleNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        String sql = "select a.TripStartTime,a.TripEndTime,b.DistID,a.StartRing as RingID,a.VID,ISNULL(c.BoxWeight,0.0) as BoxWeight from (SELECT TripStartTime,TripEndTime,StartRing,VID,StartDist FROM rtm_trip WHERE TripStartTime >= ? AND TripStartTime < ? AND PlateNum LIKE '京%')a LEFT JOIN [IDBox_Base].[dbo].[BJ_Area] b ON (a.StartDist = b.ID_POI) left JOIN (select vid,BoxWeight from IDBox_Master.dbo.stat_month_userPortrait where statMonth = ? and statYear = ?) c ON a.VID = c.VID";
        try{
            ArrayList<DistVehicle> distVehicleList = getTripDistVehicleNum(statTime,sql);

            Map<Integer,Map<String,VehicleNum>> distVehicleNumMap = processFireVehicleNum(distVehicleList);

            //赋值更新区域画像的最大在线车辆数
            for(int id : distVehicleNumMap.keySet()){
                //由间隔五分钟的时间字符串作为key，车辆数及扩样车辆数对象作为value
                Map<String,VehicleNum> fiveMinuteVehicleNum = distVehicleNumMap.get(id);
                int maxVehicleNum = getNum(fiveMinuteVehicleNum);
                int maxVehicleNumExt = getNumExt(fiveMinuteVehicleNum);

                DistPortrait distPortrait = distPortraitMap.get(id);
                if(distPortrait != null){
                    distPortrait.setBjMaxFireNum(maxVehicleNum);
                    distPortrait.setBjMaxFireNumExt(maxVehicleNumExt);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 4.3 获取非京牌车最大点火车辆数
     * @param statTime
     * @param distPortraitMap
     */
    private void getNotBJMaxFireVehicleNum(String[] statTime, HashMap<Integer, DistPortrait> distPortraitMap) {
        String sql = "select a.TripStartTime,a.TripEndTime,b.DistID,a.StartRing as RingID,a.VID,ISNULL(c.BoxWeight,0.0) as BoxWeight from (SELECT TripStartTime,TripEndTime,StartRing,VID,StartDist FROM rtm_trip WHERE TripStartTime >= ? AND TripStartTime < ? AND PlateNum NOT LIKE '京%')a LEFT JOIN [IDBox_Base].[dbo].[BJ_Area] b ON (a.StartDist = b.ID_POI) left JOIN (select vid,BoxWeight from IDBox_Master.dbo.stat_month_userPortrait where statMonth = ? and statYear = ?) c ON a.VID = c.VID";
        try{
            ArrayList<DistVehicle> distVehicleList = getTripDistVehicleNum(statTime,sql);

            Map<Integer,Map<String,VehicleNum>> distVehicleNumMap = processFireVehicleNum(distVehicleList);

            //赋值更新区域画像的最大在线车辆数
            for(int id : distVehicleNumMap.keySet()){
                //由间隔五分钟的时间字符串作为key，车辆数及扩样车辆数对象作为value
                Map<String,VehicleNum> fiveMinuteVehicleNum = distVehicleNumMap.get(id);
                int maxVehicleNum = getNum(fiveMinuteVehicleNum);
                int maxVehicleNumExt = getNumExt(fiveMinuteVehicleNum);

                DistPortrait distPortrait = distPortraitMap.get(id);

                if(distPortrait != null){
                    distPortrait.setNotBJMaxFireNum(maxVehicleNum);
                    distPortrait.setNotBJMaxFireNumExt(maxVehicleNumExt);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 附1：获取传入参数中的最大车辆数
     * @param fiveMinuteVehicleNum
     * @return
     */
    private int getNum(Map<String, VehicleNum> fiveMinuteVehicleNum) {
        int maxVehicleNum = 0;
        for(String time : fiveMinuteVehicleNum.keySet()){
            int vehicleNum = fiveMinuteVehicleNum.get(time).getNum();
            if(vehicleNum > maxVehicleNum){
                maxVehicleNum = vehicleNum;
            }
        }
        return maxVehicleNum;
    }

    /**
     * 附2：获取传入参数中的扩样后最大车辆数
     * @param stringVehicleNumMap
     * @return
     */
    private int getNumExt(Map<String, VehicleNum> stringVehicleNumMap) {
        int maxVehicleNumExt = 0;
        for(String time : stringVehicleNumMap.keySet()){
            int vehicleNumExt = (int)Math.floor(stringVehicleNumMap.get(time).getNumExt());
            if(vehicleNumExt > maxVehicleNumExt){
                maxVehicleNumExt = vehicleNumExt;
            }
        }
        return maxVehicleNumExt;
    }
}
